/*  This file is part of the comicconquer project
    Copyright (C) 2010 Reach <reach334@gmail.com>

    ComicConquer is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This software is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public 
    License along with this software.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "Configuration.h"

/**
 * Constructor.
 * 
 * @author reach (5/25/2010)
 */
CoconProfile::CoconProfile()
{
    m_configMap[QString("Option")]  = Cf_Option;
    m_configMap[QString("MaxMargin")]   = Cf_MaxMargin;
    m_configMap[QString("IgnoreSize")]   = Cf_IgnoreSize;
    m_configMap[QString("MinDegree")]   = Cf_MinDegree;
    m_configMap[QString("Grayscale")]   = Cf_Grayscale;
    m_configMap[QString("FileDir")]   = Cf_FileDir;
    m_configMap[QString("PageNumber")] = Cf_PageNum;
    m_configMap[QString("FlushMode")] = Cf_FlushMode;
    m_configMap[QString("ClearInterval")] = Cf_ClearInterval;
    m_configMap[QString("SideWardsDirect")] = Cf_SideWardsDirect;
    m_configMap[QString("MoveDistance")] = Cf_MoveDistance;
    m_configMap[QString("ScrollMark")] = Cf_ScrollMark;
    m_configMap[QString("Date")] = Cf_Date;

    initProfile();
}

/**
 * Init the key map.
 * 
 * @author reach (5/25/2010)
 */
void CoconProfile::initKeyMap()
{
    keyMap[Qt::Key_Menu]    = Oper_Menu;
    keyMap[Qt::Key_Escape]  = Oper_Close;
    keyMap[Qt::Key_PageUp]  = Oper_ScrollUp;
    keyMap[Qt::Key_PageDown]    = Oper_ScrollDown;
    keyMap[Qt::Key_Return]  = Oper_StatusDlg;
    keyMap[Qt::Key_Up]  = Oper_MoveUp;
    keyMap[Qt::Key_Down]    = Oper_MoveDown;
    keyMap[Qt::Key_Left]    = Oper_MoveLeft;
    keyMap[Qt::Key_Right]   = Oper_MoveRight;
}

/**
 * Initialize the gesture map.
 * 
 * @author reach (5/25/2010)
 */
void CoconProfile::initGestureMap()
{
    gestureMap[DragClick] = Oper_Origin;
    gestureMap[DragUp]        = Oper_ScrollDown;
    gestureMap[DragDown]  = Oper_ScrollUp;
    gestureMap[DragLeft]  = Oper_ScrollRight;
    gestureMap[DragRight] = Oper_ScrollLeft;

    // up down
    gestureMap[19]  = Oper_Menu;

    // up left
    gestureMap[20]  = Oper_GotoPage;

    // up right
    gestureMap[21]  = Oper_Grayscale;

    // down right
    gestureMap[29]  = Oper_AddBookmark;

    // left right
    gestureMap[37]  = Oper_Refresh;

    // right up
    gestureMap[42]  = Oper_MoveDown;

    // right down
    gestureMap[43]  = Oper_MoveUp;

    // right left
    gestureMap[44]  = Oper_StatusDlg;

    // up down left 
    gestureMap[156] = Oper_PrevComic;

    // up down right
    gestureMap[157] = Oper_NextComic;

    // up left down
    gestureMap[163] = Oper_Close;

    // up right down
    gestureMap[171] = Oper_Close;

    // down left up
    gestureMap[226] = Oper_FileBrowser;

    // down right up
    gestureMap[234] = Oper_FileBrowser;

    // right down left
    gestureMap[348] = Oper_ManageBookmark;
}

/**
 * Initialize the profile properties before read config files.
 * 
 * @author reach (5/25/2010)
 */
void CoconProfile::initProfile()
{
    initKeyMap();
    initGestureMap();

#ifdef QT_ARCH_ARM
    filePath = QString("/media/sd");
#else
    filePath = QString("/media");
#endif

    iPage = -1; // -1 indicate that there is no comic loaded now
    iDivPage = 0;
    iSideWardsDirect = 0;
    iFlushMode = 0;
    iClearInterval = 6;
    iMoveDistance = 20;
    iScrollMark = 1;

    grayscale.black = 0;
    grayscale.middle = 1.0f;
    grayscale.white = 255;

    imgProfile.option = Opt_DividePage | Opt_FitToWidth | Opt_RightToLeft | Opt_CutMargin | Opt_Align | Opt_ScrollMode;
    imgProfile.maxMarginPercent = 30;
    imgProfile.minDegree = 0.5f;
    imgProfile.ignoreSize = 30;

    isZip = false;

    readProfile();

    if (filePath.endsWith(".zip", Qt::CaseInsensitive))
    {
        isZip = true;
    }

    readLocalConfig();
}

/**
 * Read all the config files in installation directory.
 * 
 * @author reach (5/25/2010)
 */
void CoconProfile::readProfile()
{
    //-- read config.ini
    readConfig();

    //-- read bookmark.txt
    readBookmarks();

    //-- read key.map
    QFile keyFile(KEYFILE_NAME);
    if (keyFile.exists() && keyFile.open(QIODevice::ReadOnly))
    {
        QDataStream in(&keyFile); 
        QVector<qint32> data;
        while (!in.atEnd())
        {
            qint32 inNum;
            in>>inNum; 
            data.append(inNum);
        }
        keyFile.close();

        if (data.count() >= 2)
        {
            keyMap.clear();
        }

        for (int i = 1; i < data.count(); i+=2)
        {
            keyMap[data[i-1]] = data[i]; 
        }
    }

    //-- read gesture.map
    QFile gestureFile(GESTUREFILE_NAME);
    if (gestureFile.exists() && gestureFile.open(QIODevice::ReadOnly))
    {
        QDataStream in(&gestureFile); 
        QVector<qint32> data;
        while (!in.atEnd())
        {
            qint32 inNum;
            in>>inNum; 
            data.append(inNum);
        }
        gestureFile.close();

        if (data.count() >= 2)
        {
            gestureMap.clear();
        }

        for (int i = 1; i < data.count(); i+=2)
        {
            gestureMap[data[i-1]] = data[i]; 
        }
    }
}

/**
 * Write all the config files in installation directory and current comic directory.
 * 
 * @author reach (5/25/2010)
 */
void CoconProfile::writeProfile()
{
    //-- write config.ini
    writeConfig();

    writeLocalConfig();

    //-- write key.map
    QFile keyFile(KEYFILE_NAME);
    if (keyFile.open(QIODevice::WriteOnly))
    {
        QDataStream out(&keyFile);
        QList<qint32> keys = keyMap.keys();
        for (int i = 0; i < keys.count(); i++)
        {
            out<<keys[i]<<keyMap[keys[i]];
        }

        keyFile.close();
    }

    //-- write gesture.map
    QFile gestureFile(GESTUREFILE_NAME);
    if (gestureFile.open(QIODevice::WriteOnly))
    {
        QDataStream out(&gestureFile);
        QList<qint32> keys = gestureMap.keys();
        for (int i = 0; i < keys.count(); i++)
        {
            out<<keys[i]<<gestureMap[keys[i]];
        }

        keyFile.close();
    }
}

/**
 * Read cocon.ini.
 * 
 * @author reach (5/25/2010)
 * 
 * @param filename: Path of the cocon.ini to read.
 */
void CoconProfile::readConfig(const QString filename)
{
    In_Log(__FUNCTION__);

    QFile file(filename);
    if (file.exists() && file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        QTextStream in(&file);
        while (!in.atEnd())
        {
            QString line = in.readLine(); 
            QStringList list = line.split(" ", QString::SkipEmptyParts);
            QString name = list.at(0);
            name.chop(1);

            if (list.count() < 2 || !m_configMap.contains(name))
            {
                continue; 
            }

            switch (m_configMap[name])
            {
            case Cf_Option:
                {
                    bool ok;
                    int inNum = list[1].toInt(&ok);
                    if (ok)
                    {
                        imgProfile.option = inNum;
                    }
                }
                break;
            case Cf_MaxMargin:
                {
                    bool ok;
                    int inNum = list[1].toInt(&ok);
                    if (ok)
                    {
                        imgProfile.maxMarginPercent = inNum;
                    }
                }
                break;
            case Cf_IgnoreSize:
                {
                    bool ok;
                    int inNum = list[1].toInt(&ok);
                    if (ok)
                    {
                        imgProfile.ignoreSize = inNum;
                    }
                }
                break;
            case Cf_FlushMode:
                {
                    bool ok;
                    int inNum = list[1].toInt(&ok);
                    if (ok)
                    {
                        iFlushMode = inNum;
                    }
                }
                break;
            case Cf_ClearInterval:
                {
                    bool ok;
                    int inNum = list[1].toInt(&ok);
                    if (ok)
                    {
                        iClearInterval = inNum;
                    }
                }
                break;
            case Cf_SideWardsDirect:
                {
                    bool ok;
                    int inNum = list[1].toInt(&ok);
                    if (ok)
                    {
                        iSideWardsDirect = inNum;
                    }
                }
                break;
            case Cf_MoveDistance:
                {
                    bool ok;
                    int inNum = list[1].toInt(&ok);
                    if (ok)
                    {
                        iMoveDistance = inNum;
                    }
                }
                break;
            case Cf_ScrollMark:
                {
                    bool ok;
                    int inNum = list[1].toInt(&ok);
                    if (ok)
                    {
                        iScrollMark = inNum;
                    }
                }
                break;
            case Cf_MinDegree:
                {
                    bool ok;
                    float inNum = list[1].toFloat(&ok);
                    if (ok)
                    {
                        imgProfile.minDegree = inNum;
                    }
                }
                break;
            case Cf_Grayscale:
                {
                    if (list.count() < 4)
                    {
                        break; 
                    }

                    bool ok = false;
                    int iBlack;
                    float fMiddle;
                    int iWhite;

                    iBlack = list[1].toInt(&ok);
                    fMiddle = list[2].toFloat(&ok);
                    iWhite = list[3].toInt(&ok);

                    if (ok)
                    {
                        grayscale.black = iBlack;
                        grayscale.white = iWhite;

                        // To be compatiable with low versions.
                        if (fMiddle < 10.0f)
                        {
                            grayscale.middle = fMiddle;
                        }
                    }
                }
                break;
            case Cf_FileDir:
                {
                    filePath = list[1]; 
                    for (int i = 2; i < list.count(); i++)
                    {
                        filePath += " " + list[i];
                    }
                }
                break;
            case Cf_PageNum:
                {
                    if (list.count() < 3)
                    {
                        break; 
                    }

                    bool ok = false;
                    int inNum[2];
                    for (int i = 1; i < 3; i++)
                    {
                        inNum[i-1] = list[i].toInt(&ok); 
                    }

                    if (ok)
                    {
                        iPage = inNum[0];
                        iDivPage = inNum[1];
                    }
                }
                break;
            default:
                {

                }
                break;
            }
        }
        file.close();
    }

    Out_Log(__FUNCTION__);
}

/**
 * Write cocon.ini.
 * 
 * @author reach (5/25/2010)
 * 
 * @param filename: The path of cocon.ini to write.
 */
void CoconProfile::writeConfig(const QString filename)
{
    In_Log(__FUNCTION__);

    Write_Log(filename + "\n");

    // do not write to local file when there is no comic loaded
    if (filename != CONFIGFILE_NAME && iPage == -1)
    {
        Write_Log("don't write, iPage = %d\n, iPage");
        return;
    }

    QFile file(filename);
    if (file.open(QIODevice::WriteOnly | QIODevice::Text))
    {
        QTextStream out(&file);

        // option
        out<<m_configMap.key(Cf_Option)<<"= "<<imgProfile.option<<"\n";

        // maxMargin
        out<<m_configMap.key(Cf_MaxMargin)<<"= "<<imgProfile.maxMarginPercent<<"\n";

        // ignoreSize
        out<<m_configMap.key(Cf_IgnoreSize)<<"= "<<imgProfile.ignoreSize<<"\n";

        // flushMode
        out<<m_configMap.key(Cf_FlushMode)<<"= "<<iFlushMode<<"\n";

        // clearInterval
        out<<m_configMap.key(Cf_ClearInterval)<<"= "<<iClearInterval<<"\n";

        // minDegree
        out<<m_configMap.key(Cf_MinDegree)<<"= "<<imgProfile.minDegree<<"\n";

        // grayscale
        out<<m_configMap.key(Cf_Grayscale)<<"= "<<grayscale.black<<" "<<grayscale.middle<<" "<<grayscale.white<<"\n";

        // sidewardsDirect
        if (filename == CONFIGFILE_NAME)
        {
            out<<m_configMap.key(Cf_SideWardsDirect)<<"= "<<iSideWardsDirect<<"\n";
        }

        // moveDistance
        if (filename == CONFIGFILE_NAME)
        {
            out<<m_configMap.key(Cf_MoveDistance)<<"= "<<iMoveDistance<<"\n";
        }

        // scrollMark
        if (filename == CONFIGFILE_NAME)
        {
            out<<m_configMap.key(Cf_ScrollMark)<<"= "<<iScrollMark<<"\n";
        }

        // pageNumber
        if (filename != CONFIGFILE_NAME)
        {
            out<<m_configMap.key(Cf_PageNum)<<"= "<<iPage<<" "<<iDivPage<<"\n";
        }

        // fileDir
        if (filename == CONFIGFILE_NAME)
        {
            out<<m_configMap.key(Cf_FileDir)<<"= "<<filePath<<"\n";
        }

        file.close();
    }

    Out_Log(__FUNCTION__);
}

/**
 * Read cocon_zip.ini.
 * 
 * @author reach (5/25/2010)
 */
void CoconProfile::readZipConfig()
{
    In_Log(__FUNCTION__);

    QFile file(filePath.section('/', 0, -2, QString::SectionIncludeLeadingSep) + CONFIGFILE_ZIP_NAME);

    if (file.exists() && file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        QTextStream in(&file);
        bool startRead = false;
        while (!in.atEnd())
        {
            QString line = in.readLine(); 

            if (!startRead)
            {
                if (line.startsWith('['))
                {
                    QString comicFileName = line.mid(1, line.count() - 2);
                    if (comicFileName == filePath)
                    {
                        startRead = true;
                    }
                }

                continue;
            }

            if (line.startsWith('['))
            {
                break;
            }

            QStringList list = line.split(" ", QString::SkipEmptyParts);
            QString name = list.at(0);
            name.chop(1);

            if (list.count() < 2 || !m_configMap.contains(name))
            {
                continue; 
            }

            switch (m_configMap[name])
            {
            case Cf_Option:
                {
                    bool ok;
                    int inNum = list[1].toInt(&ok);
                    if (ok)
                    {
                        imgProfile.option = inNum;
                    }
                }
                break;
            case Cf_MaxMargin:
                {
                    bool ok;
                    int inNum = list[1].toInt(&ok);
                    if (ok)
                    {
                        imgProfile.maxMarginPercent = inNum;
                    }
                }
                break;
            case Cf_IgnoreSize:
                {
                    bool ok;
                    int inNum = list[1].toInt(&ok);
                    if (ok)
                    {
                        imgProfile.ignoreSize = inNum;
                    }
                }
                break;
            case Cf_FlushMode:
                {
                    bool ok;
                    int inNum = list[1].toInt(&ok);
                    if (ok)
                    {
                        iFlushMode = inNum;
                    }
                }
                break;
            case Cf_ClearInterval:
                {
                    bool ok;
                    int inNum = list[1].toInt(&ok);
                    if (ok)
                    {
                        iClearInterval = inNum;
                    }
                }
                break;
            case Cf_SideWardsDirect:
                {
                    bool ok;
                    int inNum = list[1].toInt(&ok);
                    if (ok)
                    {
                        iSideWardsDirect = inNum;
                    }
                }
                break;
            case Cf_MoveDistance:
                {
                    bool ok;
                    int inNum = list[1].toInt(&ok);
                    if (ok)
                    {
                        iMoveDistance = inNum;
                    }
                }
                break;
            case Cf_ScrollMark:
                {
                    bool ok;
                    int inNum = list[1].toInt(&ok);
                    if (ok)
                    {
                        iScrollMark = inNum;
                    }
                }
                break;
            case Cf_MinDegree:
                {
                    bool ok;
                    float inNum = list[1].toFloat(&ok);
                    if (ok)
                    {
                        imgProfile.minDegree = inNum;
                    }
                }
                break;
            case Cf_Grayscale:
                {
                    if (list.count() < 4)
                    {
                        break; 
                    }

                    bool ok = false;
                    int iBlack;
                    float fMiddle;
                    int iWhite;

                    iBlack = list[1].toInt(&ok);
                    fMiddle = list[2].toFloat(&ok);
                    iWhite = list[3].toInt(&ok);

                    if (ok)
                    {
                        grayscale.black = iBlack;
                        grayscale.white = iWhite;

                        // To be compatiable with low versions.
                        if (fMiddle < 10.0f)
                        {
                            grayscale.middle = fMiddle;
                        }
                    }
                }
                break;
            case Cf_FileDir:
                {
                    filePath = list[1]; 
                    for (int i = 2; i < list.count(); i++)
                    {
                        filePath += " " + list[i];
                    }
                }
                break;
            case Cf_PageNum:
                {
                    if (list.count() < 3)
                    {
                        break; 
                    }

                    bool ok = false;
                    int inNum[2];
                    for (int i = 1; i < 3; i++)
                    {
                        inNum[i-1] = list[i].toInt(&ok); 
                    }

                    if (ok)
                    {
                        iPage = inNum[0];
                        iDivPage = inNum[1];
                    }
                }
                break;
            default:
                {

                }
                break;
            }
        }
        file.close();
    }

    Out_Log(__FUNCTION__);
}

/**
 * Write cocon_zip.ini.
 * 
 * @author reach (5/25/2010)
 */
void CoconProfile::writeZipConfig()
{
    In_Log(__FUNCTION__);

    Write_Log(filePath + "\n");

    // do not write to local file when there is no comic loaded
    if (iPage == -1)
    {
        Write_Log("don't write, iPage = %d\n, iPage");
        return;
    }

    QFile file(filePath.section('/', 0, -2, QString::SectionIncludeLeadingSep) + CONFIGFILE_ZIP_NAME);

    QStringList fileBuffer;
    if (file.exists() && file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        QTextStream in(&file);
        bool startRemove = false;
        bool endRemove = false;
        while (!in.atEnd())
        {
            QString line = in.readLine(); 

            if (!startRemove)
            {
                if (line.startsWith('['))
                {
                    QString comicFileName = line.mid(1, line.count() - 2);
                    if (comicFileName == filePath)
                    {
                        startRemove = true;
                        continue;
                    }
                }
            }

            if (startRemove && !endRemove)
            {
                if (line.startsWith('['))
                {
                    endRemove = true;
                }
                else
                {
                    continue;
                }
            }

            fileBuffer<<line;
        }

        file.close();
    }

    if (file.open(QIODevice::WriteOnly | QIODevice::Text))
    {
        QTextStream out(&file);

        // fileBuffer
        for (int i = 0; i < fileBuffer.count(); i++)
        {
            out<<fileBuffer[i]<<"\n";
        }

        // filePath
        out<<"["<<filePath<<"]\n";

        // option
        out<<m_configMap.key(Cf_Option)<<"= "<<imgProfile.option<<"\n";

        // maxMargin
        out<<m_configMap.key(Cf_MaxMargin)<<"= "<<imgProfile.maxMarginPercent<<"\n";

        // ignoreSize
        out<<m_configMap.key(Cf_IgnoreSize)<<"= "<<imgProfile.ignoreSize<<"\n";

        // flushMode
        out<<m_configMap.key(Cf_FlushMode)<<"= "<<iFlushMode<<"\n";

        // clearInterval
        out<<m_configMap.key(Cf_ClearInterval)<<"= "<<iClearInterval<<"\n";

        // minDegree
        out<<m_configMap.key(Cf_MinDegree)<<"= "<<imgProfile.minDegree<<"\n";

        // grayscale
        out<<m_configMap.key(Cf_Grayscale)<<"= "<<grayscale.black<<" "<<grayscale.middle<<" "<<grayscale.white<<"\n";

        // pageNumber
        out<<m_configMap.key(Cf_PageNum)<<"= "<<iPage<<" "<<iDivPage<<"\n";

        file.close();
    }

    Out_Log(__FUNCTION__);
}

/**
 * Read cocon.ini or cocon_zip.ini. Redirect to the right function.
 * 
 * @author reach (5/25/2010)
 */
void CoconProfile::readLocalConfig()
{
    In_Log(__FUNCTION__);

    if (isZip)
    {
        readZipConfig();
    }
    else
    {
        readConfig(filePath + CONFIGFILE_LOCAL_NAME);
    }

    Out_Log(__FUNCTION__);
}

/**
 * Write cocon.ini or cocon_zip.ini. Redirect to the right function.
 * 
 * @author reach (5/25/2010)
 */
void CoconProfile::writeLocalConfig()
{
    In_Log(__FUNCTION__);

    if (isZip)
    {
        writeZipConfig();
    }
    else
    {
        writeConfig(filePath + CONFIGFILE_LOCAL_NAME);
    }

    Out_Log(__FUNCTION__);
}

/**
 * Read the bookmark file.
 * 
 * @author reach (5/25/2010)
 */
void CoconProfile::readBookmarks()
{
    In_Log(__FUNCTION__);

    QFile file(BOOKMARK_NAME);
    if (file.exists() && file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        bookmarks.clear();

        Bookmark bookmark;

        QTextStream in(&file);
        while (!in.atEnd())
        {
            QString line = in.readLine(); 
            QStringList list = line.split(" ", QString::SkipEmptyParts);
            QString name = list.at(0);
            name.chop(1);

            if (list.count() < 2 || !m_configMap.contains(name))
            {
                continue; 
            }

            switch (m_configMap[name])
            {
            case Cf_FileDir:
                {
                    if (!bookmark.path.isEmpty())
                    {
                        bookmarks.append(bookmark);
                    }

                    bookmark.path = list[1]; 
                    for (int i = 2; i < list.count(); i++)
                    {
                        bookmark.path += " " + list[i];
                    }

                }
                break;

            case Cf_Date:
                {
                    bookmark.date = list[1];
                }
                break;

            default:
                break;
            }
        }

        if (!bookmark.path.isEmpty())
        {
            bookmarks.append(bookmark);
        }

        file.close();
    }

    Out_Log(__FUNCTION__);
}

/**
 * Write the bookmark file.
 * 
 * @author reach (5/25/2010)
 */
void CoconProfile::writeBookmarks()
{
    In_Log(__FUNCTION__);

    QFile file(BOOKMARK_NAME);

    if (file.open(QIODevice::WriteOnly | QIODevice::Text))
    {
        QTextStream out(&file);

        for (int i = 0; i < bookmarks.count(); i++)
        {
            out<<m_configMap.key(Cf_FileDir)<<"= "<<bookmarks[i].path<<"\n";
            out<<m_configMap.key(Cf_Date)<<"= "<<bookmarks[i].date<<"\n";
        }

        file.close();
    }

    Out_Log(__FUNCTION__);
}

/**
 * Add a comic to bookmark.
 * 
 * @author reach (5/25/2010)
 */
void CoconProfile::addBookmark()
{
    In_Log(__FUNCTION__);

    for (int i = 0; i < bookmarks.count(); i++)
    {
        if (bookmarks[i].path == filePath)
        {
            bookmarks.removeAt(i);
        }
    }

    Bookmark bookmark;
    bookmark.path = filePath;
    bookmark.date = QDateTime::currentDateTime().toString("yyyy-MM-dd");
    bookmarks.push_front(bookmark);

    writeBookmarks();

    Out_Log(__FUNCTION__);
}

/**
 * Remove a comic.
 * 
 * @author reach (5/25/2010)
 * 
 * @param id: The id of comic to remove.
 */
void CoconProfile::removeBookmark(int id)
{
    In_Log(__FUNCTION__);

    bookmarks.removeAt(id);
    writeBookmarks();

    Out_Log(__FUNCTION__);
}

QString CoconProfile::toString()
{
    In_Log(__FUNCTION__);

    return QString("FilePath: %1\n"
                   "iPage: %2\n"
                   "iDivPage: %3").arg(filePath).arg(iPage).arg(iDivPage);

    Out_Log(__FUNCTION__);
}
